package com.trade.module.daq.service.impl;

import com.trade.common.resultcode.CollRuleCode;
import com.trade.common.resultcode.CollRuleMsg;
import com.trade.common.utils.Constants;
import com.trade.common.utils.ResponseBean;
import com.trade.common.utils.UnionStringUtil;
import com.trade.common.utils.XaUtil;
import com.trade.module.daq.entity.SystemInfo;
import com.trade.module.daq.repository.*;
import com.trade.module.daq.service.CollectionRuleService;
import com.trade.module.daq.vo.TableInfoParamVo;
import com.trade.module.daq.entity.CollectRule;
import com.trade.module.daq.entity.FieldInfo;
import com.trade.module.daq.entity.TableInfo;
import com.trade.common.resultcode.BaseResultCode;
import com.trade.common.resultcode.BaseResultMsg;
import com.trade.common.scheduler.TaskRunnable;
import com.trade.common.scheduler.TaskSchedulerManager;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Class Description: 采集规则服务层
 *
 * @Version v1.0 2017/6/21 23:46
 * @JDK version 1.8.0_51
 * @Author zfb
 */
@Service
@Transactional
public class CollectionRuleServiceImpl implements CollectionRuleService {

    @Autowired
    private SystemInfoRepository systemInfoRepository;

    @Autowired
    private CollectRuleRepository collectRuleRepository;

    @Autowired
    private TaskSchedulerManager taskSchedulerManager;

    @Autowired
    private TableInfoRepository tableInfoRepository;

    @Autowired
    private FileInfoRepository fieldInfoRepository;

    @Autowired
    private CollectionRecordRepository collectRecordRepository;

    @Autowired
    private TableRecordRepository tableRecordRepository;

    /**
     * 新建采集规则
     * @param rule 采集规则对象
     * @return ResponseBean
     */
    @Override
    public ResponseBean save(CollectRule rule) throws Exception {
        if (!UnionStringUtil.isContainBlank(rule.getRuleName(),rule.getTargetID(),rule.getSourceID()).equals("03")) {
            return new ResponseBean(CollRuleCode.PARAM_IS_NULL,CollRuleMsg.PARAM_IS_NULL);
        }
        //设置定时状态
        if(rule.getIsTiming().equals(Constants.YesOrNo.YES)){ //即时
            rule.setStatus(Constants.COLLECT_STATUS01);    //启用
        } else { //定时
            rule.setStatus(Constants.COLLECT_STATUS01);    //禁用
        }
        rule.setDataFlag(Constants.DATA_FLAG_OK);
        collectRuleRepository.save(rule);

        //如果是即时的，则开始执行任务（y:及时任务，n：定时任务）
        if (Constants.YesOrNo.YES.equals(rule.getIsTiming())) {
            return excuteTask(rule);
        }
        return new ResponseBean(BaseResultCode.REST_SUCCESS_CODE,BaseResultMsg.REST_SUCCESS_MSG);
    }

    /**
     * 根据采集规则启动任务
     * @param rule 采集规则
     * @return ResponseBean
     * @throws Exception 异常
     */
    @Override
    public ResponseBean excuteTask(CollectRule rule) throws Exception {
        if (rule == null) {
            return new ResponseBean(CollRuleCode.StartTask.RULE_IS_NULL,CollRuleMsg.StartTask.RULE_IS_NULL);
        }
        //检测定时任务是否正在执行中
        if (taskSchedulerManager.isRunning(rule.getId())) {
            return new ResponseBean(CollRuleCode.StartTask.TASK_IS_RUN,CollRuleMsg.StartTask.TASK_IS_RUN);
        }

        String inSourceID = rule.getSourceID();  //输入id
        String outSourceID = rule.getTargetID(); //输出id
        if (!UnionStringUtil.isContainBlank(inSourceID,outSourceID).equals("03")) {
            return new ResponseBean(CollRuleCode.PARAM_IS_NULL,CollRuleMsg.PARAM_IS_NULL);
        }
        SystemInfo outSource = systemInfoRepository.findByIdAndDataFlag(outSourceID, Constants.DATA_FLAG_OK);
        SystemInfo inSource = systemInfoRepository.findByIdAndDataFlag(inSourceID, Constants.DATA_FLAG_OK);
        if (inSource == null || outSource == null) {
            return new ResponseBean(CollRuleCode.StartTask.SOURCE_IS_NULL,CollRuleMsg.StartTask.SOURCE_IS_NULL);
        }

        //获取目标系统下的所有表信息集合
        List<TableInfo> outTables = tableInfoRepository.findBySystemIdAndDataFlag(outSourceID, Constants.DATA_FLAG_OK);
        if (XaUtil.isEmpty(outTables)) {
            return new ResponseBean(CollRuleCode.StartTask.OUTTABLE_IS_NULL,CollRuleMsg.StartTask.OUTTABLE_IS_NULL);
        }

        //封装数据源 目标源所需的参数
        List<TableInfoParamVo> inTableInfoParam = new ArrayList<>();
        List<TableInfoParamVo> outTableInfoParam = new ArrayList<>();
        String[] inTableArray = new String[outTables.size()];

        for (int i = 0; i < outTables.size(); i++) {
            TableInfo outTable = outTables.get(i);
            //通过关联表id查询关联的源表集合
            List<TableInfo> inTables = tableInfoRepository.findByRelTableIdAndDataFlag(outTable.getRelTableId(), Constants.DATA_FLAG_OK);

            if (XaUtil.isEmpty(inTables)) {
                return new ResponseBean(CollRuleCode.StartTask.INTABLE_IS_NULL,CollRuleMsg.StartTask.INTABLE_IS_NULL);
            }
            TableInfo inTable = inTables.get(0);
            //目标表字段集合
            List<FieldInfo> outFieldList = fieldInfoRepository.findByTableInfoIdAndDataFlag(outTable.getId(), Constants.DATA_FLAG_OK);
            //源表字段集合
            List<FieldInfo> inFieldList = fieldInfoRepository.findByTableInfoIdAndDataFlag(inTable.getId(), Constants.DATA_FLAG_OK);

            TableInfoParamVo outTableInfoParamVo = new TableInfoParamVo();
            TableInfoParamVo inTableInfoParamVo = new TableInfoParamVo();
            BeanUtils.copyProperties(outTableInfoParamVo, outTable);
            BeanUtils.copyProperties(inTableInfoParamVo, inTable);
            outTableInfoParamVo.setFieldInfoList(outFieldList);
            outTableInfoParamVo.setRelTableName(inTable.getEname());
            inTableInfoParamVo.setFieldInfoList(inFieldList);
            outTableInfoParam.add(outTableInfoParamVo);
            inTableInfoParam.add(inTableInfoParamVo);
            inTableArray[i] = inTableInfoParamVo.getEname();
        }

        String isTiming = rule.getIsTiming();
        if (StringUtils.equals(Constants.YesOrNo.YES, isTiming)) { //即时
            TaskRunnable taskRunnable = new TaskRunnable(inTableArray,inSource,outSource,rule,inTableInfoParam,
                    outTableInfoParam,collectRuleRepository,tableRecordRepository,collectRecordRepository);
            //执行即时采集策略
            taskSchedulerManager.executeOneTime(taskRunnable);
        } else if (StringUtils.equals(Constants.YesOrNo.NO, isTiming)) { //定时
            TaskRunnable taskRunnable = new TaskRunnable(inTableArray,inSource,outSource,rule,inTableInfoParam,
                    outTableInfoParam,collectRuleRepository,tableRecordRepository,collectRecordRepository);
            taskSchedulerManager.start(taskRunnable);
        }
        return new ResponseBean(BaseResultCode.REST_SUCCESS_CODE,BaseResultMsg.REST_SUCCESS_MSG);
    }
}
